문서의 임의 삭제는 제재 대상으로, 문서를 삭제하려면 삭제 토론을 진행해야 합니다. 문서 보기문서 삭제토론 칼만 필터 (문단 편집) == 칼만필터 구현과정 == 칼만필터를 구현하기 위한 알고리즘의 기본순서는 다음과 같다. 1. 초기값 선정 : 추정하고자하는 상태의 평균[math(x_0)]과 공분산[math(P_0)]의 초기값을 설정, 이는 어디까지나 초기값이기 때문에 공분산[math(P_0)]가 영행렬만 아니면 되긴 된다. 가령 상태 갯수가 n개라고 할때 아래와 같이 설정할 수 있다. [math(x_0=zeros(n))] [math(P_0=0.01 * eye(n))] 2. 상태값 예측 : 수식을 통해 다음 상태값을 예측하고 공분산을 계산한다. 이를 사전확률(prior)이라고도 부르는데 그냥 단순히 [math(x_k)]값으로 [math(x_{k+1})]을 계산하는 것이라고 생각하면된다. [math(\hat{x}_k^- = f(x_{k-1}))] [math(\hat{P}_k^- = AP_{k-1}A^T + Q)] 여기서 Q는 Process 노이즈의 공분산으로 예측에 사용한 수식 [math(f(x))]의 정확도를 의미한다. 대부분은 구할수 없는 값이기 때문에 이것도 그냥 [math(Q=(0.01)^2 * eye(n))]같은 식으로 설정하면 된다. 3. 칼만이득 계산 : 앞에서 설명한 대로 모델링의 부정확성 혹은 계측 오차로 인한 오차 등으로 인한 예측값과 실제값의 차이를 보정해주기 위하여 보정항에 들어가는 칼만이득 K를 구하는 과정이다. 여기서 칼만이득 K는 [math(\frac{\partial tr(P)}{\partial K}=0)]일때의 값으로 아래와 같이 계산된다. [math(K_k = \hat{P}_k^- H^T(H\hat{P}_k^- H^T + R)^{-1})] 여기서 R는 Measurement 노이즈의 공분산으로 계측기의 성능을 의미한다. 대게 제조사에서 제공하는 성능에 따라 결정하며 모르는 경우 계측기 갯수가 m개라고 할때 [math(R=(0.01)^2 * eye(m))]와 같이 설정하면 된다. 4. 예측값 보정 : 위에서 계산된 칼만이득 [math(K)]를 가지고 최종적인 추정값을 도출해내는 과정이다. 사후확률(posterior)이라고도 부르는데 그냥 기존 식에 보정항[math(K(y - \hat{y}))]을 추가하는 것 뿐이다. [math(x_k = \hat{x}_k + K_k(z_k - h(\hat{x}_k)))] [math(P_k = (I - K_k H) \hat{P}_k^-)] 사실 칼만필터를 구현하는데 필요한 수식은 매우 간단하기 때문에 구현 자체가 어렵지는 않다. 물론 경우에 따라 Jacobian을 유도하는 과정이 복잡할순 있지만 이 역시도 심볼릭 연산으로 직접 Jacobian을 직접 유도할때 이야기이고 유한차분이나 자동미분을 사용하여 간단하게 구현할 수 있으며, 무향칼만필터(UFK)등에서는 단순히 시그마포인트를 구하고 시그마포인트를 [math(f(x))], [math(h(x))]를 통과 시키면 되기 때문에 이러한 과정 조차 필요 없다. 학술 연구를 목적으로 칼만필터를 구현하고자 하는 경우 추천이 되는 방법은 라이브러리나 Toolbox를 활용하는 것이다. 가령 MATLAB에서는 알토대에서 개발한 EKF/UKF Toolbox가 가장 대표적이다. 이에 관한 80페이지 가량의 메뉴얼도 있으며 사용법도 매우 간단하다. Python에는 FilterPy 라이브러리가 있다. 애초에 학술목적으로 개발이 된 만큼 성능은 다소 아쉽지만 사용법 자체는 매우 간단하게 되어 있다. 아래는 FilterPy 라이브러리에서 무향칼만필터(UKF)의 구현 예시이다. {{{import numpy as np from filterpy.kalman import MerweScaledSigmaPoints from filterpy.kalman import UnscentedKalmanFilter class UKF: def __init__(self, n, m, dt): self.n = n # 추정하고자 하는 상태 갯수 self.m = m # 계측기 갯수 self.dt = dt # Time Step self.x_prev = np.zeros(n) # 초기 상태값 self.P_prev = 0.001 * np.eye(n) # 초기 공분산 def Statespace(self, x_prev, dt): x_pred = np.exp(x_prev) return x_pred def Measurement(self, x_pred): z = np.cos(x_pred) return z def Estimation(self, z): fx = self.Statespace hx = self.Measurement points = MerweScaledSigmaPoints(self.n, alpha=.1, beta=2., kappa=-1) ukf = UnscentedKalmanFilter(dim_x=self.n, dim_z=self.m, dt=self.dt, fx=fx, hx=hx, points=points) ukf.x = self.x_prev ukf.P = self.P_prev ukf.R = (0.01**2)* np.eye(m) # Measurement Noise 공분산 ukf.Q = (0.01**2)* np.eye(m) # Process Noise 공분산 ukf.predict() ukf.update(z) self.x_prev = ukf.x self.P_prev = ukf.P return ukf.x }}} 칼만필터가 제어공학의 끝판왕 중 하나로 취급을 받는 것은 --사실 H-infinity 같은것도 있지만 일단 무시하자-- 단순히 제어공학만 이해하면 되는것이 아닌 확률에 대한 개념도 이해를 하여야 한다는 점이다. 가령 입력 오차를 단순히 정규분포로 가정한다 하더라도 수식이 비선형이면 출력 오차의 분포는 정규분포가 아닌 다른 형태를 갖게된다. 그리고 이 분포를 구하는 정형된 방법은 21세기 현재까지도 존재하지 않는다. 따라서 분포를 구하기 위해선 수식을 선형화하거나 몬테카를로 시뮬레이션과 유사한 방법을 취해야 하는데 그것이 EKF와 UKF이다. 당연한 이야기지만 몬테카를로 시뮬레이션은 컴퓨팅 파워가 충분히 좋아진 현재에 들어와서 가능해진 이야기이고 칼만필터가 처음 제안된 이후 최초로 구현된 칼만필터는 EKF이다. EKF는 단순히 수식을 선형화하는 과정을 포함하고 있을 뿐이라서 연산속도가 매우 빠르다는 장점을 가지고 있다. 하지만 수식의 비선형성이 매우 큰 경우 정확성이 떨어질수 있다는 제약사항을 갖고 있다. 따라서 이후에 제안된것이 UKF와 PKF이다. 대체로 수식의 비선형성보다는 확률분포의 비선형성이 낮다는점에 착안하여 확률분포를 근사화 한 방법으로 이때 확률분포가 정규분포이면 UKF, 아니면 PKF로 분류된다. 하지만 이 방법들도 앞서 설명하였다 싶이 매우 높은 컴퓨팅 파워를 요구하기 때문에 EKF에 비해 적용가능한 필드가 제한된다는 단점이 존재한다. [[분류:공학]]저장 버튼을 클릭하면 당신이 기여한 내용을 CC-BY-NC-SA 2.0 KR으로 배포하고,기여한 문서에 대한 하이퍼링크나 URL을 이용하여 저작자 표시를 하는 것으로 충분하다는 데 동의하는 것입니다.이 동의는 철회할 수 없습니다.캡챠저장미리보기